﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections;
using System.Text;
using System.Web.Script.Serialization;
using System.Globalization;
using Assignment_3.Classes;

namespace Assignment_3.Feature___Reports
{
    public partial class RoomOccupancyReport : System.Web.UI.Page
    {
        #region Control Methods
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Session["username"] == null || Session["usertype"] == null)
            {
                Response.Redirect("~/Feature - Users/Login.aspx");
            }

            if (((string)Session["usertype"]) == "Reception")
            {
                Response.Redirect("~/Other - Error Pages/NoPermission.aspx");
            }

            if (!IsPostBack)
            {
                startdateTbx.Attributes.Add("ReadOnly", "true");
                enddateTbx.Attributes.Add("ReadOnly", "true");
                string currentdate = DateTime.Now.ToString("yyyy-MM-dd");
                startdateTbx.Text = currentdate;
                enddateTbx.Text = currentdate;
                enddateTbx_CalendarExtender.EndDate = Convert.ToDateTime(currentdate).AddDays(6);
                chartPanel.Visible = false;
            }
        }


        protected void SearchBtn_Click(object sender, EventArgs e)
        {
            emptyLbl.Text = "";
            List<RoomOccupancy> roomoccupancyList = DatabaseManager.getRoomOccupancyReport(startdateTbx.Text, enddateTbx.Text);//"04/04/2013", "05/05/2013");
            DateTime startdate = Convert.ToDateTime(startdateTbx.Text);
            DateTime enddate = Convert.ToDateTime(enddateTbx.Text);
            if (roomoccupancyList.Count != 0)
            {
                chartPanel.Visible = true;

                //Draw Table Chart
                StringBuilder data2 = new StringBuilder();
                JavaScriptSerializer json2 = new JavaScriptSerializer();
                json2.Serialize(roomoccupancyList, data2);
                hdData2.Value = data2.ToString();

                string period = periodRbl.SelectedItem.Text;
                //Establish List to store data into Column Chart
                List<ROChart> columnList = new List<ROChart>();
                //Establish List to store data into Pie Chart
                List<ROChart> pieList = new List<ROChart>();
                double totalpercentage = 0.0;
                int periodlength = 0;

                //Get data for daily
                if (period.Equals("Daily"))
                {
                    //Column Chart - % of Room Occupied based on date range
                    for (var day = startdate.Date; day.Date <= enddate.Date; day = day.AddDays(1))
                    {
                        ROChart ro = new ROChart();
                        Object[] roomoccupancy = DatabaseManager.getRoomOccupancyByDay(day);
                        ro.Period = (string)roomoccupancy[0];
                        ro.Percentage = (double)roomoccupancy[1];
                        columnList.Add(ro);
                        //Calculate total percentage for Pie Chart
                        totalpercentage += ro.Percentage;
                    }
                    //Pie Chart - Average % of room occupied
                    periodlength = (enddate - startdate).Days + 1;
                    pieList = calculatePie(totalpercentage, periodlength);

                }
                else if (period.Equals("Weekly"))
                {
                    //Get Week Number from start/end date
                    CultureInfo ciCurr = CultureInfo.CurrentCulture;
                    int startnum = ciCurr.Calendar.GetWeekOfYear(startdate, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Sunday);
                    int endnum = ciCurr.Calendar.GetWeekOfYear(enddate, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Sunday);

                    //Column Chart - % of Room Occupied based on week number
                    if (endnum >= startnum)
                    {
                        //Column Chart - % of Room Occupied based on week number
                        for (int i = startnum; i <= endnum; i++)
                        {
                            Object[] roomoccupancy = DatabaseManager.getRoomOccupancyByWeek(i, startdate.Year);
                            int someYear = startdate.Year;
                            ROChart ro = calculateWeek(roomoccupancy, someYear);
                            columnList.Add(ro);
                            //Calculate total percentage for Pie Chart
                            totalpercentage += ro.Percentage;
                            periodlength = endnum - startnum + 1;
                        }
                    }
                    else
                    {
                        string parsedate = "31.12." + startdate.Year;
                        DateTime parse = DateTime.Parse(parsedate);
                        int maxnum = ciCurr.Calendar.GetWeekOfYear(parse, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Sunday);
                        int year = startdate.Year;
                        int weekno = startnum;
                        for (int i = startnum; i <= (maxnum + endnum); i++)
                        {
                            Object[] roomoccupancy = DatabaseManager.getRoomOccupancyByWeek(weekno, year);
                            ROChart ro = calculateWeek(roomoccupancy, year);
                            columnList.Add(ro);
                            if (i == maxnum)
                            {
                                year = enddate.Year;
                                weekno = 1;
                            }
                            //Calculate total percentage for Pie Chart
                            totalpercentage += ro.Percentage;
                            weekno++;
                        }
                        periodlength = maxnum - startnum + endnum + 1;
                    }

                    //Pie Chart - Average % of room occupied
                    pieList = calculatePie(totalpercentage, periodlength);
                }
                else if (period.Equals("Monthly"))
                {
                    int startmonth = startdate.Month;
                    int endmonth = enddate.Month;
                    int startyear = startdate.Year;
                    int endyear = enddate.Year;
                    if (endmonth >= startmonth && endyear == startyear)
                    {
                        //Column Chart - % of Room Occupied based on month
                        for (int i = startmonth; i <= endmonth; i++)
                        {
                            Object[] roomoccupancy = DatabaseManager.getRoomOccupancyByMonth(startdate);
                            ROChart ro = calculateMonth(roomoccupancy);
                            columnList.Add(ro);
                            //Calculate total percentage for Pie Chart
                            totalpercentage += ro.Percentage;
                            startdate = startdate.AddMonths(1);
                        }
                        periodlength = endmonth - startmonth + 1;
        }
                    else
                    {
                        DateTime date = startdate;
                        for (int i = 0; i <= (12 - startmonth + endmonth + 1); i++)
                        {
                            Object[] roomoccupancy = DatabaseManager.getRoomOccupancyByMonth(date);
                            ROChart ro = calculateMonth(roomoccupancy);
                            columnList.Add(ro);
                            //If moving to next year
                            if (i == 12)
                            {
                                date = enddate;
    }
                            date = date.AddMonths(1);
}
                        periodlength = 12 - startmonth + endmonth + 1;
                    }
                    //Pie Chart - Average % of room occupied
                    pieList = calculatePie(totalpercentage, periodlength);
                }

                //Draw Column Chart
                StringBuilder data = new StringBuilder();
                JavaScriptSerializer json = new JavaScriptSerializer();
                json.Serialize(columnList, data);
                hdData.Value = data.ToString();

                //Draw Pie Chart
                StringBuilder data3 = new StringBuilder();
                JavaScriptSerializer json3 = new JavaScriptSerializer();
                json3.Serialize(pieList, data3);
                hdData3.Value = data3.ToString();
            }

            else
            {
                emptyLbl.Text = "There is no records for this range of date.";
                chartPanel.Visible = false;
            }
        }

        protected void periodRbl_SelectedIndexChanged(object sender, EventArgs e)
        {
            emptyLbl.Text = "";
            startdateTbx.Text = "";
            enddateTbx.Text = "";
            startdateVld.IsValid = false;
            enddateTbx.Enabled = false;

        }

        protected void startdateTbx_TextChanged(object sender, EventArgs e)
        {
            enddateTbx.Text = "";
            if (startdateTbx.Text != "")
            {
                enddateTbx.Enabled = true;
                enddateTbx_CalendarExtender.StartDate = Convert.ToDateTime(startdateTbx.Text);
                string period = periodRbl.SelectedItem.Text;

                // Limit enddate of the Calendar
                if (period.Equals("Daily"))
                {
                    //1 Week Limitation
                    enddateTbx_CalendarExtender.EndDate = Convert.ToDateTime(startdateTbx.Text).AddDays(6);
                }
                else if (period.Equals("Weekly"))
                {
                    //2 Months Limitation
                    enddateTbx_CalendarExtender.EndDate = Convert.ToDateTime(startdateTbx.Text).AddMonths(2);
                }
                else if (period.Equals("Monthly"))
                {
                    //1 Year Limitation
                    enddateTbx_CalendarExtender.EndDate = Convert.ToDateTime(startdateTbx.Text).AddYears(1);
                }
            }
            else
            {
                startdateVld.IsValid = false;
                enddateTbx.Enabled = false;
            }
        }
        #endregion

        #region Other methods
        //Calculate data for Pie Chart
        public List<ROChart> calculatePie(double totalcount, int periodlength)
        {
            List<ROChart> pieList = new List<ROChart>();
            ROChart occupied = new ROChart();
            occupied.Period = "Occupied";
            occupied.Percentage = Math.Round(totalcount / periodlength, 2);
            ROChart notoccupied = new ROChart();
            notoccupied.Period = "Not Occupied";
            notoccupied.Percentage = 100.0 - occupied.Percentage;
            pieList.Add(occupied);
            pieList.Add(notoccupied);
            return pieList;
        }

        public ROChart calculateWeek(Object[] roomoccupancy, int someYear)
        {
            ROChart ro = new ROChart();
            int week = (int)roomoccupancy[0];
            //Convert Week Number back to date range
            DateTime dt = new DateTime(someYear, 1, 1).AddDays((week - 1) * 7 - (week == 1 ? 0 : 1));
            string date = "";
            date = dt.AddDays(-(int)dt.DayOfWeek).ToString("dd/MM/yyyy");
            date += " to " + dt.AddDays(5).ToString("dd/MM/yyyy");

            ro.Period = date;
            ro.Percentage = (double)roomoccupancy[1];
            return ro;
        }

        public ROChart calculateMonth(Object[] roomoccupancy)
        {
            string[] months = { null, "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
            ROChart ro = new ROChart();
            //Get name of the months
            for (int x = 1; x < months.Length; x++)
            {
                if ((int)roomoccupancy[0] == x)
                {
                    ro.Period = months[x] + " " + Convert.ToString(roomoccupancy[2]);
                }
            }
            ro.Percentage = (double)roomoccupancy[1];
            return ro;
        }
        #endregion
    }

}

#region other classes
public class ROChart
{
    private string period;
    private double percentage;

    public string Period
    {
        get { return period; }
        set { period = value; }
    }

    public double Percentage
    {
        get { return percentage; }
        set { percentage = value; }
    }

}
#endregion